﻿// -----------------------------------------------------------------------
// <copyright file="DailyCalendar.cs" company="The Usual Dosage">
// © 2013 by Matthew M. Martin
// </copyright>
// -----------------------------------------------------------------------

namespace Cadence.NET.Calendars
{
    using System;
    using System.Collections.Generic;
    using Cadence.NET.BaseClasses;

    /// <summary>
    /// Describes the methods and properties of a day-based calendar.
    /// </summary>
    public class DailyCalendar : ICalendar
    {
        #region Properties

        /// <summary>
        /// Gets or sets the run days.
        /// </summary>
        /// <value>
        /// The run days.
        /// </value>
        public List<DayOfWeek> RunDays { get; set; }

        /// <summary>
        /// Gets or sets the exclude days.
        /// </summary>
        /// <value>
        /// The exclude days.
        /// </value>
        public List<DayOfWeek> ExcludeDays { get; set; }

        /// <summary>
        /// Gets or sets the override days.
        /// </summary>
        /// <value>
        /// The override days.
        /// </value>
        public List<DayOfWeek> OverrideDays { get; set; }

        /// <summary>
        /// Gets or sets the timezone offset from UTC.
        /// </summary>
        /// <value>
        /// The timezone offset.
        /// </value>
        public int? TimezoneUTCOffset 
        { 
            get; 
            set; 
        }

        /// <summary>
        /// Gets the current date time.
        /// </summary>
        public DateTime CurrentDateTime 
        { 
            get 
            {
                if (TimezoneUTCOffset.HasValue)
                    return DateTime.UtcNow.AddHours(TimezoneUTCOffset.Value);
                else
                    return DateTime.UtcNow;
            } 
        }

        #endregion Properties

        #region Constructor

        /// <summary>
        /// Initializes a new instance of the <see cref="DailyCalendar"/> class.
        /// </summary>
        /// <param name="Monday">if set to <c>true</c> [monday].</param>
        /// <param name="Tuesday">if set to <c>true</c> [tuesday].</param>
        /// <param name="Wednesday">if set to <c>true</c> [wednesday].</param>
        /// <param name="Thursday">if set to <c>true</c> [thursday].</param>
        /// <param name="Friday">if set to <c>true</c> [friday].</param>
        /// <param name="Saturday">if set to <c>true</c> [saturday].</param>
        /// <param name="Sunday">if set to <c>true</c> [sunday].</param>
        public DailyCalendar(bool Monday = false, bool Tuesday = false, bool Wednesday = false, bool Thursday = false, bool Friday = false, bool Saturday = false, bool Sunday = false)
        {
            RunDays = new List<DayOfWeek>();
            if (Monday)
                RunDays.Add(DayOfWeek.Monday);
            if (Tuesday)
                RunDays.Add(DayOfWeek.Tuesday);
            if (Wednesday)
                RunDays.Add(DayOfWeek.Wednesday);
            if (Thursday)
                RunDays.Add(DayOfWeek.Thursday);
            if (Friday)
                RunDays.Add(DayOfWeek.Friday);
            if (Saturday)
                RunDays.Add(DayOfWeek.Saturday);
            if (Sunday)
                RunDays.Add(DayOfWeek.Sunday);
        }

        #endregion Constructor

        #region Interface Implementation

        /// <summary>
        /// When implemented in a derived class, checks the time configured, and indicates whether this instance can run.
        /// </summary>
        /// <returns>
        ///   <c>true</c> if this instance can run; otherwise, <c>false</c>.
        /// </returns>
        public bool CanRun()
        {
            DayOfWeek currentDay = CurrentDateTime.DayOfWeek;

            if (OverrideDays != null && OverrideDays.Contains(currentDay))
                return true;
            else if (ExcludeDays != null && ExcludeDays.Contains(currentDay))
                return false;
            else if (RunDays.Contains(currentDay))
                return true;
            else
                return false;
        }

        #endregion Interface Implementation
    }
}
